﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace CommonLib {
    public class Screen {
        private Vector3c topLeft;
        private int width, height, length;
        private Vector3c dw, dh;
        private Vector3c eye;
        private Bitmap pixels;
        private Rectangle bmpRect;

        public Screen(Vector3c tl, Vector3c tr, Vector3c bl, int w, int h, Vector3c ey) {
            topLeft = tl;
            width = w;
            height = h;
            length = w * h;
            eye = ey;
            pixels = new Bitmap(w, h);
            bmpRect = new Rectangle(0, 0, w, h);

            //dw = (tr - tl) / w;
            //dh = (bl - tl) / h;
            dw = tr;
            dw.sub(topLeft);
            dw.div(w);
            dh = bl;
            dh.sub(topLeft);
            dh.div(h);
        }
        public Bitmap Buffer {
            get { return this.pixels; }
        }
        public BitmapData Lock() {
            return pixels.LockBits(bmpRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
        }
        public void Unlock(BitmapData bmpData) {
            pixels.UnlockBits(bmpData);
        }
        public int Size {
            get { return this.length; }
        }
        public int Width {
            get { return this.width; }
        }
        public int Height {
            get { return this.height; }
        }
        public Ray getRay(int w, int h) {
            //return new Ray(eye, topLeft + (w * dw) + (h * dh) - eye);
            Vector3c direction = topLeft;
            direction.mac(w, dw);
            direction.mac(h, dh);
            direction.sub(eye);
            return new Ray(eye, direction);
        }
        public Ray getRay(int index) {
            return getRay(index % width, index / width);
        }
        public void setPixel(int w, int h, Vector3c color) {
            color.mul(255);
            Color pix = Color.FromArgb(
                (Math.Max(0, Math.Min((int)color.x, 255))),
                (Math.Max(0, Math.Min((int)color.y, 255))),
                (Math.Max(0, Math.Min((int)color.z, 255))));

            lock (this) {
                this.pixels.SetPixel(w, h, pix);
            }
        }
        public void setPixel(int index, Vector3c color) {
            setPixel(index % width, index / width, color);
        }
    }
}
